package fr.emse.tatiana.corpus;

import org.apache.xmlrpc.XmlRpcException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

import fr.emse.tatiana.remotecontrol.RemoteControl;
import fr.emse.tatiana.replayable.Replayable;
import fr.emse.tatiana.replayable.TraceReplayer;
import fr.emse.tatiana.video.VideoController;


/**
 * Editor for displaying synchronisation information related to a corpus file. Does
 * not (yet) do any editing
 * 
 * @author dyke
 *
 */
public class CorpusFileEditor extends EditorPart implements Listener {
	
	public static final String ID = "fr.emse.tatiana.CorpusFileEditor";
	
	private CorpusFileInput input;
	
	private Button checkbox;
	
	
	public CorpusFileEditor() {
		super();
	}
	@Override
	public void dispose() {
		if (remote!=null && !remote.getEnd() && replayer!=null) {
			remote.removeReplayer(replayer);
			replayer.end();
		}
		super.dispose();
	}
	
	@Override
	public void doSave(IProgressMonitor monitor) {
		// TODO z later when we allow saving
		
	}
	
	@Override
	public void doSaveAs() {
		// TODO z later when we allow saving
		
	}
	
	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		this.input = (CorpusFileInput) input;
		setInput(input);
		setSite(site);
		setPartName(input.getName());
	}
	
	@Override
	public boolean isDirty() {
		return false;
	}
	
	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}
	
	@Override
	public void createPartControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout gl = new GridLayout();
		int ncol = 2;
		gl.numColumns = ncol;
		composite.setLayout(gl);
		Label label = new Label(composite,SWT.NONE);
		label.setText("Replayer:");
		Text text = new Text(composite,SWT.READ_ONLY /*| SWT.BORDER*/);
		text.setText(input.getCorpusFile().getReplayer());
		text.setEditable(false);
		text.setEnabled(true);
		
		label = new Label(composite,SWT.NONE);
		label.setText("Delta:");
		text = new Text(composite,SWT.READ_ONLY);
		text.setText(""+input.getCorpusFile().getDelta());
		text.setEditable(false);
		text.setEnabled(true);
		
		label = new Label(composite,SWT.NONE);
		label.setText("First Time:");
		text = new Text(composite,SWT.READ_ONLY);
		text.setText(""+input.getCorpusFile().getFirstTime());
		text.setEditable(false);
		text.setEnabled(true);
		
		label = new Label(composite,SWT.NONE);
		label.setText("Last Time:");
		text = new Text(composite,SWT.READ_ONLY);
		text.setText(""+input.getCorpusFile().getLastTime());
		text.setEditable(false);
		text.setEnabled(true);
		
				CorpusFile cf = getCorpusFile();
		if (cf.getType()==CorpusFile.VIDEO) {
			checkbox = new Button(composite,SWT.CHECK);
			checkbox.setText("Mute");
			checkbox.addListener(SWT.Selection, this);
			
		
				
				
		}
	}
	

	public void handleEvent(Event e) {
		if (this.replayer instanceof VideoController) {
				((VideoController) replayer).setMute(this.checkbox.getSelection());

		}
	}
	
	@Override
	public void setFocus() {
		// do nothing	
	}
	
	public CorpusFile getCorpusFile() {
		return input.getCorpusFile();
	}

	public static class CorpusFileInput implements IEditorInput {

		private CorpusFile cf;
		
		public CorpusFileInput(CorpusFile file) {
			this.cf = file;
		}
		
		public boolean exists() {
			return true;
		}

		public ImageDescriptor getImageDescriptor() {
			return null;
		}

		public String getName() {
			return cf.getName();
		}

		public IPersistableElement getPersistable() {
			// TODO z later make it persistable some day
			return null;
		}

		public String getToolTipText() {
			return getName();
		}

		public Object getAdapter(Class adapter) {
			return null;
		}
		
		public CorpusFile getCorpusFile() {
			return cf;
		}

		/* (non-Javadoc)
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((cf.getPath() == null) ? 0 : cf.getPath().hashCode());
			return result;
		}

		/* (non-Javadoc)
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			final CorpusFileInput other = (CorpusFileInput) obj;
			if (cf.getPath() == null) {
				if (other.cf.getPath() != null)
					return false;
			} else if (!cf.getPath().equals(other.cf.getPath()))
				return false;
			return true;
		}
		
		

	}

	private RemoteControl remote;
	private Replayable replayer;
	public void startSynchronisation (RemoteControl remote) {
		this.remote = remote;
		CorpusFile cf = getCorpusFile();
		try {
			if (cf.getType()==CorpusFile.VIDEO) {
				VideoController video = new VideoController(cf.getFirstTime(),cf.getLastTime(),cf.getDelta());
				video.openFile(cf.getPath());
				remote.addContinuousReplayer(video);
				video.setMute(this.checkbox.getSelection());
				this.replayer = video;
			} else {
				TraceReplayer replayer = null;
				if ("Drew".equalsIgnoreCase(cf.getReplayer())) {
					replayer=new TraceReplayer("drew",cf.getFirstTime(),cf.getLastTime());	
				} else if ("Coffee".equalsIgnoreCase(cf.getReplayer())) {
					replayer=new TraceReplayer("coffee",cf.getFirstTime(),cf.getLastTime());	
				} 
				if (replayer!=null) {
					replayer.openFile(cf.getPath());
					remote.addDiscreteReplayer(replayer);
					System.out.println("Added replayer"+cf.getReplayer());
					this.replayer = replayer;
					
				}
			}
		} catch (XmlRpcException ex) {
			System.err.println("Failed openFile on TraceReplayer."+cf.getReplayer());
			//e.printStackTrace();
			MessageDialog.openError(this.getSite().getShell(),"Error","Failed open "+cf.getName()+" on TraceReplayer "+cf.getReplayer());

		}
	}
	
}
